package org.hackystat.linkedservicedata.ui.users;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.LinkedList;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import org.hackystat.linkedservicedata.sparql.SparqlFilter;
import org.hackystat.linkedservicedata.sparql.UserQuery;
import org.hackystat.linkedservicedata.ui.LinkedServiceDataUI;
import org.hackystat.linkedservicedata.vocabularies.HackystatConstants;

/**
 * User search wizard panel.
 *
 * @author Myriam Leggieri.
 *
 */
public class UserSearchWizard extends JFrame implements ItemListener, ActionListener {

  /**
   * Auto-generated serial version ID.
   */
  private static final long serialVersionUID = -2448725738480402598L;

  /** Parent frame. */
  LinkedServiceDataUI mainframe = null;

  /** Name label. */
  public JLabel nameLabel = null;

  /** Surname label. */
  public JLabel surnameLabel = null;

  /** Nickname label. */
  public JLabel nickLabel = null;

  /** Email label. */
  public JLabel emailLabel = null;

  /** Homepage label. */
  public JLabel homepageLabel = null;

  /** Weblog label. */
  public JLabel weblogLabel = null;

  /** Karma label. */
  public JLabel karmaLabel = null;

  /** Karma text. */
  public JTextField karmaText = null;

  /** Name text. */
  public JTextField nameText = null;

  /** Surname text. */
  public JTextField surnameText = null;

  /** Nickname text. */
  public JTextField nickText = null;

  /** Email text. */
  public JTextField emailText = null;

  /** Homepage text. */
  public JTextField homepageText = null;

  /** Weblog text. */
  public JTextField weblogText = null;

  /** SeeAlso URI container. */
  public String[] seeAlso = null;

  /** SeeAlso URI JList. */
  public JList seeAlsoList = null;

  /** SeeAlso 'add' button. */
  public JButton seeAlsoButton = null;

  /** Search button. */
  public JButton searchButton = null;

  /** Cancel button. */
  public JButton cancelButton = null;

  /** SeeAlso label. */
  public JLabel seeAlsoLabel = null;

  /** SeeAlso text field. */
  public JTextField seeAlsoText = null;

  /** SameAs label. */
  public JLabel sameAsLabel = null;

  /** SameAs URI container. */
  public String[] sameAs = null;

  /** SameAs URI JList. */
  public JList sameAsList = null;

  /** SameAs 'add' button. */
  public JButton sameAsButton = null;

  /** SameAs text field. */
  public JTextField sameAsText = null;

  /** Sparql filters container. */
  public LinkedList<SparqlFilter> filtersList = null;

  /** Filter value text. */
  private JTextField filterValueText = null;

  /** Skills combo box. */
  private JComboBox skillsCombo = null;

  /** Skills label. */
  private JLabel filterValueLabel = null;

  /** Skills label. */
  private JLabel skillsLabel = null;

  /** Skills list label. */
  private JLabel skillsListLabel = null;

  /** SameAs list label. */
  private JLabel sameAsListLabel = null;

  /** SeeAlso list label. */
  private JLabel seeAlsoListLabel = null;

  /** JList of selected skills and values. */
  private JList skillsValueList = null;

  /** Add filter button. */
  private JButton addFilterButton = null;

  /** Remove filter button. */
  private JButton removeFilterButton = null;

  /** Add sameAs button. */
  private JButton addSameAsButton = null;

  /** Remove sameAs button. */
  private JButton removeSameAsButton = null;

  /** Add seeAlso button. */
  private JButton addSeeAlsoButton = null;

  /** Remove seeAlso button. */
  private JButton removeSeeAlsoButton = null;

  /** Greater Than check box. */
  private JCheckBox greaterThanCheckBox = null;

  /** Less Than check box. */
  private JCheckBox lessThanCheckBox = null;

  /** Equals to check box. */
  private JCheckBox equalsToCheckBox = null;

  /** Main container. */
  private Container container = null;

  /** SameAs List model. */
  private DefaultListModel sameAsListModel = null;

  /** SeeAlso List model. */
  private DefaultListModel seeAlsoListModel = null;

  /** Skills List model. */
  private DefaultListModel skillsListModel = null;

  public UserSearchWizard(LinkedServiceDataUI parent) {
    super("Hackystat - Search for users");
    mainframe = parent;
    container = this.getContentPane();
    refresh(true);
    pack();
    setSize(mainframe.popUpWinDimension);
    setLocationRelativeTo(null);
    setBackground(Color.white);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
        setVisible(false);
        dispose();
      }
    });
    setVisible(true);
  }

  public void refresh(boolean reset) {
    container.removeAll();
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.setBackground(Color.WHITE);
    if (mainframe.isLogged()) {
      initLabelHeaders1();
      initJTextFields(reset);
      panel.add(fillInUserProfileData1());
      panel.add(Box.createVerticalGlue());
      panel.add(fillInUserSkills());
      panel.add(getActions());
    }
    panel.setPreferredSize(mainframe.popUpWinDimension);
    panel.setBackground(Color.white);
    JScrollPane listScrollPane = new JScrollPane(panel);
    listScrollPane.setPreferredSize(mainframe.popUpWinDimension);
    listScrollPane.setMaximumSize(mainframe.popUpWinDimension);
    listScrollPane.setMinimumSize(mainframe.popUpWinDimension);
    container.add(listScrollPane);
    container.validate();
  }

  private void initJTextFields(boolean reset) {
    String empty = "";
    if (emailText == null || reset) {
      emailText = new JTextField(10);
      emailText = mainframe.initTextField(emailText, empty, true);
    }
    if (nameText == null || reset) {
      nameText = new JTextField(10);
      nameText = mainframe.initTextField(nameText, empty, true);
    }
    if (surnameText == null || reset) {
      surnameText = new JTextField(10);
      surnameText = mainframe.initTextField(surnameText, "", true);
    }
    if (karmaText == null || reset) {
      karmaText = new JTextField(10);
      karmaText = mainframe.initTextField(karmaText, empty, true);
    }
    if (nickText == null || reset) {
      nickText = new JTextField(10);
      nickText = mainframe.initTextField(nickText, empty, true);
    }
    if (homepageText == null || reset) {
      homepageText = new JTextField(10);
      homepageText = mainframe.initTextField(homepageText, empty, true);
    }
    if (weblogText == null || reset) {
      weblogText = new JTextField(10);
      weblogText = mainframe.initTextField(weblogText, empty, true);
    }
    if (filterValueText == null || reset) {
      filterValueText = new JTextField(10);
      filterValueText = mainframe.initTextField(filterValueText, empty, true);
    }
    if (seeAlsoText == null || reset) {
      seeAlsoText = new JTextField(10);
      seeAlsoText = mainframe.initTextField(seeAlsoText, empty, true);
    }
    if (sameAsText == null || reset) {
      sameAsText = new JTextField(10);
      sameAsText = mainframe.initTextField(sameAsText, empty, true);
    }
    return;
  }

  private JPanel fillInUserProfileData1() {
    JPanel horiz = new JPanel();
    horiz.setLayout(new BoxLayout(horiz, BoxLayout.X_AXIS));
    horiz.setBackground(Color.white);
    JPanel vertic = null;

    vertic = new JPanel();
    vertic.setLayout(new BoxLayout(vertic, BoxLayout.Y_AXIS));
    vertic.setBackground(Color.white);
    vertic.add(emailLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(emailText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(nickLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(nickText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(nameLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(nameText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(surnameLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(surnameText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(homepageLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(homepageText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(weblogLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(weblogText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(karmaLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(karmaText);
    horiz.add(vertic);
    horiz.add(Box.createHorizontalStrut(5));

    vertic = new JPanel();
    vertic.setLayout(new BoxLayout(vertic, BoxLayout.Y_AXIS));
    vertic.setBackground(Color.white);

    if (sameAsListModel == null) {
      sameAsListModel = new DefaultListModel();
    }
    sameAsList = new JList(sameAsListModel);
    sameAsList = mainframe.initJList(sameAsList);
    JScrollPane listScrollPane = new JScrollPane(sameAsList);
    listScrollPane = mainframe.initJListScrollPane(listScrollPane);
    addSameAsButton = new JButton("Add >>");
    addSameAsButton = mainframe.initButton(addSameAsButton, this, mainframe.buttonDimension,
        "Add the selected sameAs URI to the list on the right.");
    removeSameAsButton = new JButton("Remove <<");
    removeSameAsButton = mainframe.initButton(removeSameAsButton, this, mainframe.buttonDimension,
        "Remove the selected sameAs URI from the list on the right.");
    vertic.add(mainframe.addJListFillingComponent(sameAsLabel, sameAsText, addSameAsButton,
        removeSameAsButton, sameAsListLabel, listScrollPane, ""));
    vertic.add(Box.createVerticalStrut(3));

    if (seeAlsoListModel == null) {
      seeAlsoListModel = new DefaultListModel();
    }
    seeAlsoList = new JList(seeAlsoListModel);
    seeAlsoList = mainframe.initJList(seeAlsoList);
    listScrollPane = new JScrollPane(seeAlsoList);
    listScrollPane = mainframe.initJListScrollPane(listScrollPane);
    addSeeAlsoButton = new JButton("Add >>");
    addSeeAlsoButton = mainframe.initButton(addSeeAlsoButton, this, mainframe.buttonDimension,
        "Add the selected seeAlso URI to the list on the right.");
    removeSeeAlsoButton = new JButton("Remove <<");
    removeSeeAlsoButton = mainframe.initButton(removeSeeAlsoButton, this,
        mainframe.buttonDimension, "Remove the selected seeAlso URI from the list on the right.");
    vertic.add(mainframe.addJListFillingComponent(seeAlsoLabel, seeAlsoText, addSeeAlsoButton,
        removeSeeAlsoButton, seeAlsoListLabel, listScrollPane, ""));

    horiz.add(vertic);
    return horiz;
  }

  private JPanel fillInUserSkills() {
    JPanel horiz = new JPanel();
    horiz.setLayout(new BoxLayout(horiz, BoxLayout.X_AXIS));
    horiz.setBackground(Color.white);
    JPanel vertic = null;

    vertic = new JPanel();
    vertic.setLayout(new BoxLayout(vertic, BoxLayout.Y_AXIS));
    vertic.setBackground(Color.white);
    vertic.add(skillsLabel);
    vertic.add(Box.createVerticalStrut(1));
    skillsCombo = new JComboBox(HackystatConstants.SKILLS_LIST);
    mainframe.initComboBox(skillsCombo, this);
    vertic.add(skillsCombo);
    horiz.add(vertic);
    horiz.add(Box.createHorizontalStrut(5));
    vertic = new JPanel();
    vertic.setLayout(new BoxLayout(vertic, BoxLayout.Y_AXIS));
    vertic.setBackground(Color.white);
    greaterThanCheckBox = new JCheckBox(SparqlFilter.OP_GREATER_THAN);
    greaterThanCheckBox = mainframe.initCheckBox(greaterThanCheckBox, this, "Greater than", true,
        true);
    vertic.add(greaterThanCheckBox);
    vertic.add(Box.createVerticalStrut(1));
    equalsToCheckBox = new JCheckBox(SparqlFilter.OP_EQUALS_TO);
    equalsToCheckBox = mainframe.initCheckBox(equalsToCheckBox, this, "Equals to", true, false);
    vertic.add(equalsToCheckBox);
    vertic.add(Box.createVerticalStrut(1));
    lessThanCheckBox = new JCheckBox(SparqlFilter.OP_LESS_THAN);
    lessThanCheckBox = mainframe.initCheckBox(lessThanCheckBox, this, "Less than", true, false);
    vertic.add(lessThanCheckBox);
    horiz.add(vertic);
    horiz.add(Box.createHorizontalStrut(5));

    addFilterButton = new JButton("Add >>");
    addFilterButton = mainframe.initButton(addFilterButton, this, mainframe.buttonDimension,
        "Add the selected filter value to the list on the right.");
    removeFilterButton = new JButton("Remove <<");
    removeFilterButton = mainframe.initButton(removeFilterButton, this, mainframe.buttonDimension,
        "Remove the selected filter value from the list on the right.");
    if (skillsListModel == null) {
      skillsListModel = new DefaultListModel();
    }
    skillsValueList = new JList(skillsListModel);
    skillsValueList = mainframe.initJList(skillsValueList);
    JScrollPane listScrollPane = new JScrollPane(skillsValueList);
    listScrollPane = mainframe.initJListScrollPane(listScrollPane);
    horiz.add(mainframe.addJListFillingComponent(filterValueLabel, filterValueText,
        addFilterButton, removeFilterButton, skillsListLabel, listScrollPane, null));
    Border loweredetched = BorderFactory.createLineBorder(Color.blue);
    TitledBorder title = BorderFactory.createTitledBorder(loweredetched, "User's skills", 0, 0,
        new Font("Dialog", Font.BOLD, 13), Color.BLUE);
    horiz.setBorder(title);
    return horiz;
  }

  private JPanel getActions() {
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    panel.setBackground(Color.white);
    searchButton = new JButton("Search");
    searchButton = mainframe.initButton(searchButton, this, mainframe.buttonDimension,
        "Start search");
    panel.add(searchButton);
    panel.add(Box.createHorizontalStrut(5));
    cancelButton = new JButton("Cancel");
    cancelButton = mainframe.initButton(cancelButton, this, mainframe.buttonDimension,
        "Reset fields.");
    panel.add(cancelButton);
    return panel;
  }

  private void initLabelHeaders1() {
    if (filterValueLabel == null) {
      filterValueLabel = new JLabel();
      filterValueLabel = mainframe.initLabel(filterValueLabel, "Value:");
    }

    if (nameLabel == null) {
      nameLabel = new JLabel();
      nameLabel = mainframe.initLabel(nameLabel, "Name:");
    }

    if (emailLabel == null) {
      emailLabel = new JLabel();
      emailLabel = mainframe.initLabel(emailLabel, "Email:");
    }

    if (nickLabel == null) {
      nickLabel = new JLabel();
      nickLabel = mainframe.initLabel(nickLabel, "Nickname:");
    }

    if (homepageLabel == null) {
      homepageLabel = new JLabel();
      homepageLabel = mainframe.initLabel(homepageLabel, "Homepage:");
    }

    if (weblogLabel == null) {
      weblogLabel = new JLabel();
      weblogLabel = mainframe.initLabel(weblogLabel, "Weblog:");
    }

    if (surnameLabel == null) {
      surnameLabel = new JLabel();
      surnameLabel = mainframe.initLabel(surnameLabel, "Surname:");
    }

    if (skillsLabel == null) {
      skillsLabel = new JLabel();
      skillsLabel = mainframe.initLabel(skillsLabel, "Skills:");
    }

    if (karmaLabel == null) {
      karmaLabel = new JLabel();
      karmaLabel = mainframe.initLabel(karmaLabel, "Karma:");
    }

    if (sameAsLabel == null) {
      sameAsLabel = new JLabel();
      sameAsLabel = mainframe.initLabel(sameAsLabel, "SameAs URI:");
    }

    if (seeAlsoLabel == null) {
      seeAlsoLabel = new JLabel();
      seeAlsoLabel = mainframe.initLabel(seeAlsoLabel, "SeeAlso URI:");
    }

    if (skillsListLabel == null) {
      skillsListLabel = new JLabel();
      skillsListLabel = mainframe.initLabel(skillsListLabel, "List of selected skills:");
    }

    if (sameAsListLabel == null) {
      sameAsListLabel = new JLabel();
      sameAsListLabel = mainframe.initLabel(sameAsListLabel, "List of selected sameAs URI:");
    }

    if (seeAlsoListLabel == null) {
      seeAlsoListLabel = new JLabel();
      seeAlsoListLabel = mainframe.initLabel(seeAlsoListLabel, "List of selected seeAlso URI:");
    }
  }

  @Override
  public void itemStateChanged(ItemEvent e) {
    Object obj = e.getSource();
    System.out.println("in itemeventttt!");
    if (e.getStateChange() == ItemEvent.SELECTED) {
      if (obj.equals(greaterThanCheckBox)) {
        if (lessThanCheckBox.isSelected()) {
          lessThanCheckBox.setSelected(false);
        }
        if (equalsToCheckBox.isSelected()) {
          equalsToCheckBox.setSelected(false);
        }
      }
      else if (obj.equals(lessThanCheckBox)) {
        if (greaterThanCheckBox.isSelected()) {
          greaterThanCheckBox.setSelected(false);
        }
        if (equalsToCheckBox.isSelected()) {
          equalsToCheckBox.setSelected(false);
        }
      }
      else if (obj.equals(equalsToCheckBox)) {
        if (lessThanCheckBox.isSelected()) {
          lessThanCheckBox.setSelected(false);
        }
        if (greaterThanCheckBox.isSelected()) {
          greaterThanCheckBox.setSelected(false);
        }
      }
    }

  }

  @Override
  public void actionPerformed(ActionEvent e) {
    Object obj = e.getSource();
    String text = null;
    if (obj.equals(addSeeAlsoButton)) {
      text = seeAlsoText.getText();
      if (!text.startsWith("http://")) {
        JOptionPane.showMessageDialog(this, "The inserted URI must begin with 'http://'",
            "Hackystat - Error Message", JOptionPane.ERROR_MESSAGE);
        return;
      }
      seeAlsoListModel.add(seeAlsoListModel.getSize(), text);
    }
    else if (obj.equals(addSameAsButton)) {
      text = sameAsText.getText();
      if (!text.startsWith("http://")) {
        JOptionPane.showMessageDialog(this, "The inserted URI must begin with 'http://'",
            "Hackystat - Error Message", JOptionPane.ERROR_MESSAGE);
        return;
      }
      sameAsListModel.add(sameAsListModel.getSize(), text);
    }
    else if (obj.equals(addFilterButton)) {
      text = filterValueText.getText();
      if (text.contains(" ")) {
        JOptionPane.showMessageDialog(this,
            "The value inserted as a filter on skills can't contain spaces.",
            "Hackystat - Error Message", JOptionPane.ERROR_MESSAGE);
        return;
      }
      text = text.replace(".", ",");
      String comparator = greaterThanCheckBox.isSelected() ? greaterThanCheckBox.getText()
          : (lessThanCheckBox.isSelected() ? lessThanCheckBox.getText() : (equalsToCheckBox
              .isSelected() ? equalsToCheckBox.getText() : null));
      if (comparator == null) {
        JOptionPane.showMessageDialog(this, "You must select one of the available check boxes.",
            "Hackystat - Error Message", JOptionPane.ERROR_MESSAGE);
        return;
      }
      if (!text.contains(",") && !text.contains(".")) {
        text += ",0";
      }
      String filterSkill = skillsCombo.getSelectedItem().toString() + " " + comparator + " " + text;
      skillsListModel.add(skillsListModel.getSize(), filterSkill);
    }
    else if (obj.equals(removeSeeAlsoButton)) {
      if (!seeAlsoList.isSelectionEmpty()) {
        int index = seeAlsoList.getSelectedIndex();
        seeAlsoListModel.remove(index);
        seeAlsoList.repaint();
      }
      refresh(false);
    }
    else if (obj.equals(removeSameAsButton)) {
      if (!sameAsList.isSelectionEmpty()) {
        int index = sameAsList.getSelectedIndex();
        sameAsListModel.remove(index);
        sameAsList.repaint();
      }
      refresh(false);
    }
    else if (obj.equals(removeFilterButton)) {
      if (!skillsValueList.isSelectionEmpty()) {
        int index = skillsValueList.getSelectedIndex();
        skillsListModel.remove(index);
        skillsValueList.repaint();
      }
    }
    else if (obj.equals(cancelButton)) {
      refresh(true);
    }
    else if (obj.equals(searchButton)) {
      UserQuery uq = new UserQuery();
      String str = weblogText.getText(), empty = "";
      if (!str.trim().equals(empty)) {
        uq.blog = str;
      }
      str = homepageText.getText();
      if (!str.trim().equals(empty)) {
        uq.homepage = str;
      }
      str = emailText.getText();
      if (!str.trim().equals(empty)) {
        uq.email = str;
      }
      str = nameText.getText();
      if (!str.trim().equals(empty)) {
        uq.name = str;
      }
      str = nickText.getText();
      if (str != null && !str.trim().equals(empty) && !str.trim().equals("null")) {
        uq.nick = str;
      }
      str = surnameText.getText();
      if (str != null && !str.trim().equals(empty) && !str.trim().equals("null")) {
        uq.surname = str;
      }
      str = karmaText.getText();
      if (str != null && !str.trim().equals(empty) && !str.trim().equals("null")) {
        uq.karma = str;
      }
      String[] risp = mainframe.getJListContent(sameAsListModel);
      if (risp.length != 0) {
        uq.sameAs = risp;
      }
      risp = mainframe.getJListContent(seeAlsoListModel);
      if (risp.length != 0) {
        uq.seeAlso = risp;
      }
      LinkedList<SparqlFilter> sparqlFiltersList = mainframe.getSparqlFilters(skillsListModel);
      uq.filtersList = sparqlFiltersList;
      try {
        String queryResult = mainframe.getLiSeDClient().searchForUsers(uq);
        queryResult = mainframe.getURIList(queryResult);
        mainframe.displayQueryResults(queryResult);
      }
      catch (Exception e1) {
        JOptionPane.showMessageDialog(this, e1.getMessage(), "Hackystat - Error Message",
            JOptionPane.ERROR_MESSAGE);
        e1.printStackTrace();
        return;
      }
    }
  }
}
